package com.tanhua.server.service;

import com.alibaba.dubbo.common.utils.CollectionUtils;
import com.alibaba.dubbo.config.annotation.Reference;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.tanhua.dubbo.server.api.QuanZiApi;
import com.tanhua.dubbo.server.api.VisitorsApi;
import com.tanhua.dubbo.server.pojo.Publish;
import com.tanhua.dubbo.server.pojo.Visitors;
import com.tanhua.server.mapper.UserMapper;
import com.tanhua.server.pojo.User;
import com.tanhua.server.pojo.UserInfo;
import com.tanhua.server.utils.RelativeDateFormat;
import com.tanhua.server.utils.UserThreadLocal;
import com.tanhua.server.vo.Movements;
import com.tanhua.server.vo.PageResult;
import com.tanhua.server.vo.PicUploadResult;
import com.tanhua.server.vo.VisitorsVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class MovementsService {

    @Autowired
    private UserService userService;

    @Autowired
    private PicUploadService picUploadService;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Reference(version = "1.0.0")
    private QuanZiApi quanZiApi;

    @Autowired
    private UserInfoService userInfoService;
    @Autowired
    private UserMapper userMapper;
    public String savePublish(String textContent, String location, String longitude, String latitude, MultipartFile[] multipartFile) {
        User user = UserThreadLocal.get();
        //todo 校验是否为冻结发表动态
        QueryWrapper<User> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("id",user.getId());
        User user1= userMapper.selectOne(queryWrapper);
        //判断用户冻结状态
        if (user1.getFreezingRange()==3){
            String redisUserKey="FREEZEUPDATE"+user.getId();
            //判断redis缓存是否存在 不存在修改用户状态为正常
            if (!redisTemplate.hasKey(redisUserKey)){
                UpdateWrapper<User> updateWrapper=new UpdateWrapper<>();
                updateWrapper.set("freezingRange",0).set("freezingTime",0).eq("id",user1.getId());
                userMapper.update(user1,updateWrapper);
            }else {
                System.out.println(redisTemplate.getExpire(redisUserKey));
                return null;
            }
        }
        try {
            Publish publish = new Publish();
            publish.setUserId(user.getId());
            publish.setText(textContent);
            publish.setLocationName(location);
            publish.setLatitude(latitude);
            publish.setLongitude(longitude);
            publish.setSeeType(1);
            //处理文件,获得每个文件的上传的绝对路径
            List<String> picUrls = new ArrayList<>();
            for (MultipartFile file : multipartFile) {
                PicUploadResult upload = picUploadService.upload(file);
                picUrls.add(upload.getName());
            }
            publish.setMedias(picUrls);
            String publishId = quanZiApi.savePublish(publish);
            return publishId;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public PageResult queryRecommendPublishList(Integer page, Integer pageSize) {
        return getPageResult(page, pageSize, null);
    }

    public PageResult queryPublishList(Integer page, Integer pageSize) {
        User user = UserThreadLocal.get();
        return getPageResult(page, pageSize, user.getId());
    }

    public Movements queryPublishById(String publishId) {
        Publish publish = quanZiApi.queryPublishById(publishId);
        if (publish == null)
            return null;
        List<Movements> movementsList = fillValueToMovement(Arrays.asList(publish));
        return movementsList.get(0);
    }

    //获得动态
    private PageResult getPageResult(Integer page, Integer pageSize, Long userId) {
        List<Publish> publishList = null;
        //推荐查询,县从缓存中查找,若未命中,则查询MongoDB中默认数据
        if (userId == null) {
            String key = "QUANZI_PUBLISH_RECOMMEND_" + UserThreadLocal.get().getId();
            if (redisTemplate.hasKey(key)) {
                String strIds = redisTemplate.opsForValue().get(key);
                //  1,2,3,4.....
                String[] ids = strIds.split(",");
                //完成分页查询逻辑
                int startIndex = (page - 1) * pageSize;
                if (startIndex < ids.length) {
                    int endIndex = startIndex + pageSize - 1;
                    if (endIndex < ids.length) {
                        List<Long> pids = new ArrayList<>();
                        for (int i = startIndex; i <= endIndex; i++) {
                            pids.add(Long.valueOf(ids[i]));
                        }
                        publishList = quanZiApi.queryPublishByPids(pids);
                    }
                }
            }
        }
        PageResult pageResult = new PageResult();
        pageResult.setPage(page);
        pageResult.setPagesize(pageSize);
        pageResult.setPages(0);
        pageResult.setCounts(0);
        if (CollectionUtils.isEmpty(publishList)) {
            //获取时间线表中动态的集合
            publishList = quanZiApi.queryPublishList(userId, page, pageSize);
        }
        //若查询结果为空,直接返回
        if (CollectionUtils.isEmpty(publishList))
            return pageResult;
        List<Movements> resultList = fillValueToMovement(publishList);
        pageResult.setItems(resultList);
        return pageResult;
    }


    //装填数据到MovementList中
    private List<Movements> fillValueToMovement(List<Publish> publishList) {
        //后面的程序执行需要userId,查询集合后此行代码不影响好友动态和推荐动态的结果
        Long userId = UserThreadLocal.get().getId();
        Set<Long> userIds = publishList.stream().map(Publish::getUserId).collect(Collectors.toSet());
        LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(UserInfo::getUserId, userIds);
        //获取发布动态的好友信息
        List<UserInfo> userInfoList = userInfoService.queryUserInfoList(wrapper);
        //装填数据
        List<Movements> resultList = new ArrayList<>();
        for (Publish publish : publishList) {
            for (UserInfo userInfo : userInfoList) {
                if (publish.getUserId().longValue() == userInfo.getUserId().longValue()) {
                    Movements movements = new Movements();
                    movements.setId(publish.getId().toHexString());
                    movements.setImageContent(publish.getMedias().toArray(new String[]{}));
                    movements.setTextContent(publish.getText());
                    movements.setUserId(publish.getUserId());
                    movements.setCreateDate(RelativeDateFormat.format(new Date(publish.getCreated())));
                    movements.setAge(userInfo.getAge());
                    movements.setAvatar(userInfo.getLogo());
                    movements.setGender(userInfo.getSex().name().toLowerCase());
                    movements.setNickname(userInfo.getNickName());
                    movements.setTags(StringUtils.split(userInfo.getTags(), ','));
                    //TODO 评论数
                    String CommentKey = "QUANZI_COMMENT_CONTENT_" + movements.getId();
                    Integer commentCount = null;
                    if (redisTemplate.hasKey(CommentKey)) {
                        commentCount = Integer.valueOf(redisTemplate.opsForValue().get(CommentKey));
                    } else {
                        commentCount = 0;
                    }
                    movements.setCommentCount(commentCount);
                    movements.setDistance("1.2公里"); //TODO 距离
                    // TODO 是否点赞（1是，0否）
                    String likeUserCommentKey = "QUANZI_COMMENT_LIKE_" + userId + "_" + publish.getId();
                    movements.setHasLiked(redisTemplate.hasKey(likeUserCommentKey) ? 1 : 0);
                    String likeCommentKey = "QUANZI_COMMENT_LIKE_" + publish.getId();
                    //判断缓存中是否存有点赞数
                    Integer likeCount = null;
                    if (redisTemplate.hasKey(likeCommentKey)) {
                        likeCount = Integer.valueOf(redisTemplate.opsForValue().get(likeCommentKey));
                    } else {
                        likeCount = 0;
                    }
                    movements.setLikeCount(likeCount); //TODO 点赞数
                    //TODO 是否喜欢（1是，0否）
                    String loveUserCommentKey = "QUANZI_COMMENT_LOVE_" + userId + "_" + publish.getId();
                    movements.setHasLoved(redisTemplate.hasKey(loveUserCommentKey) ? 1 : 0);
                    String loveCommentKey = "QUANZI_COMMENT_LOVE_" + publish.getId();
                    //判断缓存中是否存有喜欢数
                    Integer loveCount = null;
                    if (redisTemplate.hasKey(loveCommentKey)) {
                        loveCount = Integer.valueOf(redisTemplate.opsForValue().get(loveCommentKey));
                    } else {
                        loveCount = 0;
                    }
                    movements.setLoveCount(loveCount); //TODO 喜欢数
                    resultList.add(movements);
                    break;
                }
            }
        }
        return resultList;
    }


    //点赞
    public Long likeComment(String publishId) {
        User user = UserThreadLocal.get();
        boolean flag = quanZiApi.saveLikeComment(user.getId(), publishId);
        if (!flag)
            return null;
        String likeCommentKey = "QUANZI_COMMENT_LIKE_" + publishId;
        //判断缓存中是否存有点赞数
        Long count = null;
        if (!redisTemplate.hasKey(likeCommentKey)) {
            //没有,查询获得,并放入缓存中
            count = quanZiApi.queryCommentCount(publishId, 1);
            redisTemplate.opsForValue().set(likeCommentKey, count.toString());
        } else {
            count = redisTemplate.opsForValue().increment(likeCommentKey);
        }
        // 记录当前用于已经点赞,1标记为已经点赞
        String likeUserCommentKey = "QUANZI_COMMENT_LIKE_" + user.getId() + "_" + publishId;
        redisTemplate.opsForValue().set(likeUserCommentKey, "1");
        return count;
    }

    //取消点赞
    public Long disLikeComment(String publishId) {
        User user = UserThreadLocal.get();
        boolean bool = this.quanZiApi.removeComment(user.getId(), publishId, 1);
        if (!bool) {
            return null;
        }
        //缓存中点赞数减少1
        String likeCommentKey = "QUANZI_COMMENT_LIKE_" + publishId;
        Long count = redisTemplate.opsForValue().decrement(likeCommentKey);
        //移除缓存中已点赞的标记
        String likeUserCommentKey = "QUANZI_COMMENT_LIKE_" + user.getId() + "_" + publishId;
        redisTemplate.delete(likeUserCommentKey);
        return count;
    }

    public Long loveComment(String publishId) {
        User user = UserThreadLocal.get();
        boolean flag = quanZiApi.saveLoveComment(user.getId(), publishId);
        if (!flag)
            return null;
        String loveCommentKey = "QUANZI_COMMENT_LOVE_" + publishId;
        //判断缓存中是否存有喜欢数
        Long count = null;
        if (!redisTemplate.hasKey(loveCommentKey)) {
            //没有,查询获得,并放入缓存中
            count = quanZiApi.queryCommentCount(publishId, 3);
            redisTemplate.opsForValue().set(loveCommentKey, count.toString());
        } else {
            count = redisTemplate.opsForValue().increment(loveCommentKey);
        }
        // 记录当前用于已经点赞,1标记为已经点赞
        String loveUserCommentKey = "QUANZI_COMMENT_LOVE_" + user.getId() + "_" + publishId;
        redisTemplate.opsForValue().set(loveUserCommentKey, "1");
        return count;
    }

    //取消喜欢
    public Long unLoveComment(String publishId) {
        User user = UserThreadLocal.get();
        boolean bool = this.quanZiApi.removeComment(user.getId(), publishId, 3);
        if (!bool) {
            return null;
        }
        //缓存中点喜欢数减少1
        String loveCommentKey = "QUANZI_COMMENT_LOVE_" + publishId;
        Long count = redisTemplate.opsForValue().decrement(loveCommentKey);
        //移除缓存中已点赞的标记
        String loveUserCommentKey = "QUANZI_COMMENT_LOVE_" + user.getId() + "_" + publishId;
        redisTemplate.delete(loveUserCommentKey);
        return count;
    }

    @Reference(version = "1.0.0")
    private VisitorsApi visitorsApi;

    public List<VisitorsVo> queryVisitorsList() {
        User user = UserThreadLocal.get();
        String redisKey = "visitor_date_" + user.getId();
        List<Visitors> visitors = null;
        if (redisTemplate.hasKey(redisKey)) {
            //缓存中有上次查询时间
            String time = redisTemplate.opsForValue().get(redisKey);
            visitors = visitorsApi.topVisitor(user.getId(), Long.valueOf(time));
        }else{
            visitors = visitorsApi.topVisitor(user.getId(), 5);
        }
        //如果查询结果为空,直接返回空集合
        if(CollectionUtils.isEmpty(visitors)){
            return Collections.emptyList();
        }

        //装填数据
        Set<Long> userIds = visitors.stream().map(Visitors::getVisitorUserId).collect(Collectors.toSet());
        LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(UserInfo::getUserId, userIds);
        List<UserInfo> userInfoList = this.userInfoService.queryUserInfoList(queryWrapper);
        List<VisitorsVo> visitorsVoList = new ArrayList<>();
        for (Visitors visitor : visitors) {
            for (UserInfo userInfo : userInfoList) {
                if(visitor.getVisitorUserId().longValue() == userInfo.getUserId().longValue()){
                    VisitorsVo visitorsVo = new VisitorsVo();
                    visitorsVo.setAge(userInfo.getAge());
                    visitorsVo.setAvatar(userInfo.getLogo());
                    visitorsVo.setGender(userInfo.getSex().name().toLowerCase());
                    visitorsVo.setId(userInfo.getUserId());
                    visitorsVo.setNickname(userInfo.getNickName());
                    visitorsVo.setTags(StringUtils.split(userInfo.getTags(), ','));
                    visitorsVo.setFateValue(visitor.getScore().intValue());
                    visitorsVoList.add(visitorsVo);
                    break;
                }
            }
        }
        //保存更新时间
        this.redisTemplate.opsForValue().set(redisKey,String.valueOf(System.currentTimeMillis()));
        return visitorsVoList;
    }

    public PageResult queryAlbumList(Long userId, Integer page, Integer pageSize) {
        PageResult pageResult = new PageResult();
        pageResult.setPage(page);
        pageResult.setPagesize(pageSize);

        List<Publish> publishList = this.quanZiApi.queryAlbumList(userId, page, pageSize);
        if(CollectionUtils.isEmpty(publishList)){
            return pageResult;
        }
        pageResult.setItems(this.fillValueToMovement(publishList));
        return pageResult;
    }
}
